package io.persimmon.core.entity;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class KeyValueFactory<K, V> {

    private List<KeyValue<K, V>> keyValueList = new ArrayList<>();

    public static <K, V> KeyValueFactory<K, V> create() {
        return new KeyValueFactory<>();
    }

    public static <K, V> KeyValueFactory<K, V> create(K key, V value) {
        KeyValueFactory<K, V> factory = new KeyValueFactory<>();
        factory.keyValueList.add(new KeyValue<>(key, value));
        return factory;
    }

    public KeyValueFactory<K, V> add(K key, V value) {
        this.keyValueList.add(new KeyValue<>(key, value));
        return this;
    }

    public List<KeyValue<K, V>> toList() {
        return this.keyValueList;
    }

    public Map<K, V> toMap() {
        return this.keyValueList.stream()
                .collect(Collectors.toMap(KeyValue::getKey, KeyValue::getValue, (a, b) -> b));
    }

    public Map<K, List<V>> groupByKey() {
        return this.keyValueList.stream()
                .collect(Collectors.groupingBy(KeyValue::getKey))
                .entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                        entry -> entry.getValue().stream().map(KeyValue::getValue).collect(Collectors.toList())));
    }

    public Map<K, Set<V>> groupByKeyToSet() {
        return this.keyValueList.stream()
                .collect(Collectors.groupingBy(KeyValue::getKey))
                .entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                        entry -> entry.getValue().stream().map(KeyValue::getValue).collect(Collectors.toSet())));
    }
}
